<script setup lang="ts">
import {BubbleList} from "vue-element-plus-x";
import ChatInput from "@/views/ai/agent/x6/com/ChatInput.vue";
import {BubbleListProps } from "vue-element-plus-x/types/components/BubbleList/types";
import {listType} from "@/views/ai/agent/x6/content-renderer";
import ContentWrapper from "@/views/ai/agent/x6/content-wrapper.vue";
import {BluePrintApi} from './api/blue-print-api'
import dayjs from "dayjs";
import FileWrapper from "@/views/ai/agent/x6/com/file-wrapper.vue";
import McpContentWrapper from "@/views/ai/agent/x6/mcp/mcp-content-wrapper.vue";
import './md.scss'
import {ChatInputDTO} from "@/views/ai/agent/x6/com/types";
import ThinkWrapper from "@/views/ai/agent/x6/com/think-wrapper.vue";


const bubbleItems = ref<BubbleListProps<listType>['list']>([])
const context = ref<BubbleListProps<listType>['list']>([])
const route = useRoute();
const flowId=route.params.flow as string;
const chatting=ref(false)
const hisId=ref<string>()
const slicedArray=(arr:any[],n:number)=>{
 if (arr.length>n){
   return arr.slice(arr.length-n,arr.length)
 }else {
   return arr
 }
}
const sendMsg=async (dto: ChatInputDTO)=>{
  chatting.value=true
  const sseMsg=reactive<listType>({
    role:'ai',
    placement:'end',
    chunk:[],
    loading:true,
  })
  const ums:listType={
    role:'user',
    placement:'start',
    content:dto.query,
    loading:false,
    atTime:new Date(),
    files:dto.files
  }
  bubbleItems.value.push(ums)
  if (!hisId.value){
    hisId.value=await BluePrintApi.createHis(flowId,ums)
  }
  bubbleItems.value.push(sseMsg)
  await BluePrintApi.execute(flowId,{text:dto.query,files:dto.files,context:slicedArray(context.value,5)},
    (ev)=>{
    const d=JSON.parse(ev.data)
      //{"node":"LLM_EXEC","content":null,"data":null,"status":"start"}
      if (d.node==='LLM_EXEC'&&d.status==='start'){
        sseMsg.loading=false
      }
      sseMsg.chunk?.push(d)
    },
    ()=>{
      sseMsg.atTime=new Date()
      //保存聊天历史
      if (hisId.value){
        console.log("保存聊天记录!")
        BluePrintApi.pushChat2His(hisId.value,[ums,sseMsg])
      }
      //每次完成聊天，push 到聊天上下文
      context.value.push(ums)
      const aires=sseMsg.chunk?.filter(c=>c.node==='LLM_EXEC'||c.node==='MULTIMODAL').map(chunk=>chunk.content).join('')
      context.value.push({
        content:aires,
        role:'ai'
      })
      chatting.value=false
    },
    undefined,
    (e)=>{
      ElMessage.error(e.msg)
    }
  )
}
onMounted(()=>{})

const getNow=(now:Date)=>{
  return  dayjs(now).format('YYYY年MM月DD HH:mm:ss')
}
</script>

<template>
 <div class="chat">
   <div class="body">
     <BubbleList class="body-inner" :list="bubbleItems" max-height="100%">
       <!-- 自定义头像 -->
       <template #avatar="{ item }">
         <div class="avatar-wrapper">
           <el-avatar :size="32" >{{item.role}}</el-avatar>
         </div>
       </template>

       <!-- 自定义头部 -->
       <template #header="{ item }">
         <div class="header-wrapper">
           <div class="header-name" :class="item.role">
             {{ item.role === 'ai' ? 'AI' : '我' }}
           </div>
         </div>
         <div v-if="item.chunk">
           <file-wrapper :item="item"/>
           <think-wrapper :item="item"/>
         </div>
       </template>

       <!-- 自定义气泡内容 -->
       <template #content="{ item }">
         <div class="content-wrapper">
           <div v-if="item.role==='user'">
             {{item.content}}
             <div v-if="item?.files">
               <div v-for="(img,index) in item.files" :key="index">
                 <img class="msg-img" :src="img" alt=""/>
               </div>
             </div>
           </div>
           <template v-else>
             <content-wrapper :item="item"/>
           </template>
         </div>
       </template>

       <!-- 自定义底部 -->
       <template #footer="{ item }">
         <div class="footer-wrapper">
           <div class="footer-container">
             <mcp-content-wrapper :item="item"/>
           </div>
           <div class="footer-time" :class="item.role" v-if="item.atTime">
             {{ getNow(item.atTime) }}
           </div>
         </div>
       </template>

       <!-- 自定义 loading -->
       <template #loading>
         <div class="loading-container">
           <span>回</span>
           <span>复</span>
           <span>中</span>
           <span>。</span>
           <span>。</span>
           <span>。</span>
           <span>。</span>
           <span>。</span>
           <span>。</span>
           <span>。</span>
           <span>。</span>
         </div>
       </template>
     </BubbleList>
   </div>
   <div class="fool">
     <ChatInput :loading="chatting" @query="sendMsg"/>
   </div>
 </div>
</template>

<style scoped lang="scss">
.chat{
  height: calc(
    100vh - var(--top-tool-height) - var(--tags-view-height) - var(--app-footer-height) - var(--app-content-padding)
  );
  width: 100%;
  display: flex;
  flex-direction: column;
  gap: 10px;
  .fool{
    display: flex;
    flex-direction: column;
    justify-content: flex-end;
  }
  .body{
    flex: 1;
    overflow:hidden;
    width: 100%;
    background-color: white;
    padding: 10px;
    .body-inner{
      max-width: 1000px;
      margin: 0 auto;
      overflow-x: hidden;
    }
  }
}
.isSelect {
  color: #626aef;
  border: 1px solid #626aef !important;
  border-radius: 15px;
  padding: 3px 12px;
  font-weight: 700;
}
.loading-container {
  font-size: 14px;
  color: #333;
}

.loading-container span {
  display: inline-block;
  margin-left: 8px;
}

@keyframes bounce {
  0%, 100% {
    transform: translateY(5px);
  }
  50% {
    transform: translateY(-5px);
  }
}

.loading-container span:nth-child(4n) {
  animation: bounce 1.2s ease infinite;
}
.loading-container span:nth-child(4n+1) {
  animation: bounce 1.2s ease infinite;
  animation-delay: .3s;
}
.loading-container span:nth-child(4n+2) {
  animation: bounce 1.2s ease infinite;
  animation-delay: .6s;
}
.loading-container span:nth-child(4n+3) {
  animation: bounce 1.2s ease infinite;
  animation-delay: .9s;
}
.header-wrapper{
  width: var(--bubble-content-max-width);
  max-width: var(--bubble-content-max-width);
  .header-name.ai{
    text-align: right;
  }
}
.content-wrapper{
  padding: 0px;
}

.footer-wrapper{
  width: var(--bubble-content-max-width);
  max-width: var(--bubble-content-max-width);
  .footer-time.ai{
    text-align: right;
  }
}
.msg-img{
  width: 50%
}
.loading-container{
  padding: 0px;
}
</style>
